package com.huawang.mdesign.model.service.util;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.huawang.business.constants.ErrorCode;
import com.huawang.business.constants.SystemConstants;
import com.huawang.business.dto.ColumnInfo;
import com.huawang.business.exception.AbortExecutionException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.jetbrains.annotations.NotNull;
import org.mozilla.universalchardet.UniversalDetector;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
public final class ImportAndExportUtils {
    private ImportAndExportUtils() {
        throw new IllegalStateException("Utility class");
    }

    @NotNull
    public static String getCsvEncoding(String filePath) {
        byte[] bytes = FileUtil.readBytes(new File(filePath));
        String defaultEncoding = "UTF-8";
        UniversalDetector detector = new UniversalDetector(null);
        detector.handleData(bytes, 0, bytes.length);
        detector.dataEnd();
        String encoding = Objects.equals(defaultEncoding, detector.getDetectedCharset()) ?
                defaultEncoding : "GBK";
        detector.reset();
        return encoding;
    }

    public static void toExcel(List<List<String>> headList, List<List<Object>> dataList, File file, String sheetName) throws FileNotFoundException {
        // 定义文件输出位置
        FileOutputStream outputStream = new FileOutputStream(file);
        ExcelTypeEnum excelType;
        if (file.getPath().endsWith(ExcelTypeEnum.CSV.getValue())) {
            excelType = ExcelTypeEnum.CSV;
        } else if (file.getPath().endsWith(ExcelTypeEnum.XLS.getValue())) {
            excelType = ExcelTypeEnum.XLS;
        } else if (file.getPath().endsWith(ExcelTypeEnum.XLSX.getValue())) {
            excelType = ExcelTypeEnum.XLSX;
        } else {
            log.error("导出文件格式不符合要求");
            throw AbortExecutionException.build(ErrorCode.ERROR_FILE_FORMAT);
        }
        EasyExcelFactory.write(outputStream).excelType(excelType).head(headList).sheet(sheetName).doWrite(dataList);
    }


    /**
     * 生成一个 map key 为number ; value 为instanceId
     *
     * @param stringMap
     * @return
     */
    public static Map<String, String> transformMap(Map<String, String> stringMap) {
        return stringMap.entrySet().stream()
                .collect(Collectors.toMap(
                        entry -> extractNumber(entry.getValue()), // 提取 number 作为键
                        Map.Entry::getKey,  // 值是外层 Map 的键
                        (existing, replacement) -> existing // 处理键冲突，保留现有值
                ));
    }

    /**
     * 提取字符串中空格后面的数据，如果不存在空格则返回原始字符串
     *
     * @param value 原始字符串
     * @return 提取后的 number 或原始字符串
     */
    public static String extractNumber(String value) {
        if (StrUtil.isBlank(value)) {
            return value;
        }
        List<String> parts = StrUtil.split(value, ' ', 2); // 只分割一次
        if (parts.size() > 1) {
            return parts.get(1);
        } else {
            return value;
        }
    }

    @NotNull
    public static Pair<Integer, ColumnInfo> getIdentityColumnInfo(@NotNull List<ColumnInfo> columnInfos,
                                                                  @NotNull String identityKey,
                                                                  boolean isGlobalImport) {
        ColumnInfo identityColumnInfo = columnInfos.stream().filter(it -> {
            if (isGlobalImport) {
                return (Objects.equals(it.getKey(), identityKey) && Objects.equals(it.getPropertyType(), 0)) ||
                        (it.getClassifierProperty() != null && Objects.equals(it.getClassifierProperty().getId(), identityKey));
            } else {
                return StringUtils.equals(it.getKey(), identityKey);
            }
        }).findFirst().orElseThrow(() -> AbortExecutionException.build(ErrorCode.PARAM_ERROR));
        if (identityColumnInfo == null) {
            log.error("查找不到标识属性对应属性列");
            throw AbortExecutionException.build(ErrorCode.PARAM_ERROR);
        }
        int identityIndex = columnInfos.indexOf(identityColumnInfo);
        return Pair.of(identityIndex, identityColumnInfo);
    }

    public static void sortMappingColumns(@NotNull List<String> mappingColumns) {
        LogUtil.printSerializeOnlineLogs("mappingColumns: ", mappingColumns);
        Comparator<String> columnComparator = (column1, column2) -> {
            String[] mappingColumn1 = column1.split(SystemConstants.MAPPING_COLUMNS_SEPARATOR);
            String[] mappingColumn2 = column2.split(SystemConstants.MAPPING_COLUMNS_SEPARATOR);
            if (mappingColumn1.length < 1 || mappingColumn2.length < 1) {
                log.error("mappingColumns映射列不包含分隔符__");
                throw AbortExecutionException.build(ErrorCode.QUERY_MODEL_ERROR);
            }
            String title1 = mappingColumn1[0];
            String title2 = mappingColumn2[0];
            // String自带compareTo方法会将长的排在前面
            return Objects.equals(title1.length(), title2.length()) ?
                    title1.compareTo(title2) : title1.length() - title2.length();
        };
        mappingColumns.sort(columnComparator);
        log.info("排序后的导入配置图映射关系为:{}", mappingColumns);
    }

    public static int convertLetterToNumber(String[] firstColumn) {
        int key = 65;
        int num = 0;
        for (String s : firstColumn) {
            num = num + s.charAt(0) - key;
        }
        return num;
    }
}
